#ifndef __VIDEO_RTSP_CLIENT_STREAM_H__
#define __VIDEO_RTSP_CLIENT_STREAM_H__

#include <map>
#include <mutex>
#include <string>
#include <functional>
#include "Pal/VideoDec.h"
#include "json.h"
// #include "StreamClient.h"
#include "Thread/Thread.h"
#include "StreamComposeMgr.h"
#include "AudioDecode.h"
#include "Poller/Timer.h"
#include "frame_common.h"
#include <queue>

namespace Media{

class VideoDecode;

void SetMediaStreamCreater(FrameCommon::StreamPlayCreater::Ptr creater);
FrameCommon::StreamPlayCreater::Ptr GetStreamCreater();

class RtspClientStream{
public:
	const uint16_t QueueSize = 100;
    struct FrameBuffer 
	{
	    uint64_t timestamp; /*< timestamp*/
		size_t size; /*< data length*/
		uint8_t* data; /*< raw data*/

		FrameBuffer(size_t len)
		: timestamp(0)
		, size(len)
		, data(NULL)
		{
			data = new uint8_t[len];
		}

		~FrameBuffer()
		{
			delete []data;
			data = NULL;
		}

		FrameBuffer(const FrameBuffer&);
		FrameBuffer& operator=(const FrameBuffer&);
	};

    typedef std::shared_ptr<FrameBuffer> FramePtr;
public:
	// static RtspClientStream *instance(int channel){return nullptr;}
	// bool start(StreamPlayInfo playInfo){return false;}
	// bool stop(){return false;}
	static RtspClientStream *instance(int channel);

	static RtspClientStream *GetInstance(int channel);

	bool stop();

	bool start(StreamPlayInfo playInfo);

	bool onFrame(const FrameCommon::Frame::Ptr &frame);

	bool onStop();
	
	void SetDirectFrameCallBack(const FrameCommon::frame_callback_func callback);

private:
	RtspClientStream(int channel);

	bool setFormat(VideoDecFormat *format);

	bool streamStart();
	
	bool streamStop(void);

	bool sendVideoPacket(unsigned char *buffer, int buflen, uint64_t timestamp);

    bool sendAudioPacket(unsigned char *buffer, int buflen);

	bool SaveToCommQueue(FramePtr& msg);

    bool GetCommQueueMsg(FramePtr& msg);

    void StreamInProc(Fdt::Thread *thread);

	bool clearVideoQueue();

private:
	static std::map<int, RtspClientStream *> sm_streamMap;

	static std::recursive_mutex 			sm_mapMutex;
    
    VideoDecode *                           m_pVideoDecode = nullptr;
	
	int 									m_videoChannel = -1;
	
	bool									m_started = false;

	VideoDecPacket                          m_videoPacket;

	FrameCommon::StreamPlayer::Ptr 			m_streamClient;

	std::string                             m_rtspUrl; 

	std::shared_ptr<Fdt::Timer>             m_taskTimer;

	TaskInfo                                m_taskInfo = {0};

	StreamAbility                           m_playAbility = VIDEO_AUDIO;

	AudioDecode*                            m_pAudioDecode = nullptr;

	AudioDecPacket                          m_audioPacket;

    int 									m_audioChannel = -1;

    bool                                    m_dropFrame = true;
	
	FrameCommon::frame_callback_func        m_frame_call_back = nullptr;

	std::map<void *, FrameCommon::frame_callback_func> m_frame_call_map;

    int                                     m_channel = -1;

    char                                    m_iBuffer[655350];
    
    int                                     m_bufIndex = 0;

    std::mutex                              m_queueMutex;
	
    std::queue<FramePtr>                    m_frameaQueue;

    FramePtr                                m_framePtr;

    Fdt::Thread 						    m_streamInThread{"RtspClientStreamSave"};
	
	Fdt::Thread 						    m_thread{"RtspClientStream"};

};

}//namespace Media
#endif



